home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / share / dos / graficos / plydat14.arj / COIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-29  |  6.1 KB  |  214 lines

  1. /*
  2.  * coil.c - Create a coil of n turns between two points in space
  3.  *
  4.  * Alexander Enzmann
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #ifdef MAC
  11. #include <console.h>
  12. #endif
  13. #include "def.h"
  14. #include "lib.h"
  15.  
  16. static void
  17. determine_coil_point(COORD4 *pos, COORD4 *norm,
  18.              double theta, double phi, double r0, double r1, double d0)
  19. {
  20.    COORD4 v0, v1, vd;
  21.    double len;
  22.  
  23.    /* Center of the coil */
  24.    SET_COORD4(v0, r0 * cos(theta), r0 * sin(theta), d0, 1.0);
  25.  
  26.    /* Point on the coil */
  27.    SET_COORD4(*pos, (r0 + r1 * sin(phi)) * cos(theta),
  28.             (r0 + r1 * sin(phi)) * sin(theta),
  29.             (r1 * cos(phi)) + d0,
  30.             1.0);
  31.  
  32.    /* Direction from center to point */
  33.    SUB3_COORD(vd, *pos, v0);
  34.    len = lib_normalize_coord3(&vd);
  35.  
  36.    v0.x = r1*cos(phi)*cos(theta);
  37.    v1.x = -(r0 + r1*sin(phi))*sin(theta);
  38.  
  39.    v0.y = r1*cos(phi)*sin(theta);
  40.    v1.y = (r0 + r1*sin(phi))*cos(theta);
  41.  
  42.    v0.z = -r1*sin(phi);
  43.    v1.z = 0.0;
  44.  
  45.    CROSS(*norm, v0, v1);
  46.    len = lib_normalize_coord3(norm);
  47.  
  48.    len = DOT_PRODUCT(*norm, vd);
  49.    if (len < 0.0) {
  50.       norm->x *= -1.0;
  51.       norm->y *= -1.0;
  52.       norm->z *= -1.0;
  53.       }
  54.    norm->w = 0.0;
  55. }
  56.  
  57. static void
  58. generate_coil(COORD4 *start, COORD4 *end,
  59.          int turns, int step_per_turn, int step_per_side,
  60.          double r0, double r1, char *txname)
  61. {
  62.    int i, j, k;
  63.    COORD4 p0, p[4], n0, n[4];
  64.    COORD4 dir;
  65.    MATRIX trans;
  66.    double dist, u0, u1, v0, v1, d0, d1, len;
  67.    double deltad, deltau, deltav;
  68.  
  69.    SUB3_COORD(dir, *end, *start);
  70.    dist = lib_normalize_coord3(&dir);
  71.  
  72.    /* Coils are sorta complex, so make bounding slabs oriented along
  73.       the direction of the coil */
  74.    lib_output_bounding_slab(&dir);
  75.  
  76.    /* Figure out the transform to get from the parametrically defined
  77.       coil to the start-end line */
  78.    lib_create_canonical_matrix(trans, start, &dir);
  79.  
  80.    deltad = dist / (double)(turns * step_per_turn);
  81.    deltau = 2.0 * PI / (double)step_per_turn;
  82.    deltav = 2.0 * PI / (double)step_per_side;
  83.  
  84.    /* Start generating the triangles in the coil */
  85.    for (i=0,d0=0.0;i<turns;i++) {
  86.       for (j=0;j<step_per_turn;j++,d0+=deltad) {
  87.          d1 = d0 + deltad;
  88.      u0 = (double)j * deltau;
  89.      u1 = u0 + deltau;
  90.      for (k=0;k<step_per_side;k++) {
  91.         v0 = (double)k * deltav;
  92.         v1 = v0 + deltav;
  93.  
  94.         /* Make the vertices of this patch on the coil */
  95.         determine_coil_point(&p0, &n0, u0, v0, r0, r1, d0);
  96.         lib_transform_coord(&p[0], &p0, trans);
  97.         lib_transform_coord(&n[0], &n0, trans);
  98.         determine_coil_point(&p0, &n0, u0, v1, r0, r1, d0);
  99.         lib_transform_coord(&p[1], &p0, trans);
  100.         lib_transform_coord(&n[1], &n0, trans);
  101.         determine_coil_point(&p0, &n0, u1, v1, r0, r1, d1);
  102.         lib_transform_coord(&p[2], &p0, trans);
  103.         lib_transform_coord(&n[2], &n0, trans);
  104.  
  105.         /* Make triangles out of the vertices */
  106.         /* lib_output_polygon(3, &p[0], txname); */
  107.         lib_output_polypatch(3, &p[0], &n[0], txname);
  108.  
  109.         COPY_COORD4(p[1], p[2]); COPY_COORD4(n[1], n[2]);
  110.         determine_coil_point(&p0, &n0, u1, v0, r0, r1, d1);
  111.         lib_transform_coord(&p[2], &p0, trans);
  112.         lib_transform_coord(&n[2], &n0, trans);
  113.         /* lib_output_polygon(3, &p[0], txname); */
  114.         lib_output_polypatch(3, &p[0], &n[0], txname);
  115.         }
  116.      }
  117.       }
  118. }
  119.  
  120. static void
  121. generate_cyl_coil(COORD4 *start, COORD4 *end,
  122.          int turns, int step_per_turn,
  123.          double r0, double r1, char *txname)
  124. {
  125.    int i, j, k;
  126.    COORD4 p, p0, p1, n0;
  127.    COORD4 dir;
  128.    MATRIX trans;
  129.    double dist, u0, u1, d0, d1, len;
  130.    double deltad, deltau;
  131.  
  132.    SUB3_COORD(dir, *end, *start);
  133.    dist = lib_normalize_coord3(&dir);
  134.  
  135.    /* Coils are sorta complex, so make bounding slabs oriented along
  136.       the direction of the coil */
  137.    lib_output_bounding_slab(&dir);
  138.  
  139.    /* Figure out the transform to get from the parametrically defined
  140.       coil to the start-end line */
  141.    lib_create_canonical_matrix(trans, start, &dir);
  142.  
  143.    deltad = dist / (double)(turns * step_per_turn);
  144.    deltau = 2.0 * PI / (double)step_per_turn;
  145.  
  146.    /* Start generating the cylinders making up the coil */
  147.    for (i=0,d0=0.0;i<turns;i++) {
  148.       for (j=0;j<step_per_turn;j++,d0+=deltad) {
  149.          d1 = d0 + deltad;
  150.      u0 = (double)j * deltau;
  151.      u1 = u0 + deltau;
  152.      determine_coil_point(&p, &n0, u0, 0.0, r0, 0.0, d0);
  153.      lib_transform_coord(&p0, &p, trans);
  154.      p0.w = r1;
  155.      determine_coil_point(&p, &n0, u1, 0.0, r0, 0.0, d1);
  156.      lib_transform_coord(&p1, &p, trans);
  157.      p1.w = r1;
  158.      lib_output_cylcone(&p0, &p1, txname);
  159.      lib_output_sphere(&p0, txname);
  160.      }
  161.       }
  162.    /* Cap the end */
  163.    lib_output_sphere(&p1, txname);
  164. }
  165.  
  166. void
  167. main(int argc, char *argv[])
  168. {
  169.     COORD4  back_color, coil_color, dir;
  170.     COORD4  center_pt, end_pt, light;
  171.     COORD4  from, at, up;
  172.     char *txname;
  173.  
  174.     MATRIX m1, m2;
  175.  
  176. #ifdef MAC
  177.    argc = ccommand(&argv);
  178. #endif
  179.  
  180.     /* output viewpoint */
  181.     SET_COORD(from, 0.0, 3.0,-8.0);
  182.     SET_COORD(at,   0.0, 0.0, 5.0);
  183.     SET_COORD(up,   0.0, 1.0, 0.0);
  184.     lib_output_viewpoint( &from, &at, &up, 30.0, 1.0, 1.0, 256, 256);
  185.  
  186.     /* output background color - dark blue */
  187.     SET_COORD( back_color, 0.039, 0.18, 0.376 ) ;
  188.     lib_output_background_color( &back_color ) ;
  189.  
  190.     /* Output bounding slabs oriented along the coordinate axes */
  191.     SET_COORD(dir, 1.0, 0.0, 0.0);
  192.     lib_output_bounding_slab(&dir);
  193.     SET_COORD(dir, 0.0, 1.0, 0.0);
  194.     lib_output_bounding_slab(&dir);
  195.     SET_COORD(dir, 0.0, 0.0, 1.0);
  196.     lib_output_bounding_slab(&dir);
  197.  
  198.     /* output light source */
  199.     SET_COORD( light,-10.0, 10.0,-20.0) ;
  200.     lib_output_light( &light ) ;
  201.     SET_COORD( light, 10.0, 10.0,-20.0) ;
  202.     lib_output_light( &light ) ;
  203.  
  204.     /* output coil color - red */
  205.     SET_COORD( coil_color, 1.0, 0.2, 0.2 ) ;
  206.     txname = lib_output_color(&coil_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0) ;
  207.  
  208.     /* compute and output coil */
  209.     SET_COORD4(center_pt,-1.0,-1.0, 0.0, 1.0);
  210.     SET_COORD4(end_pt, 1.0, 3.0, 4.0, 1.0);
  211.     /* generate_coil(¢er_pt, &end_pt, 5, 12, 6, 1.0, 0.3, txname); */
  212.     generate_cyl_coil(¢er_pt, &end_pt, 5, 12, 1.0, 0.3, txname);
  213. }
  214.